#! /usr/bin/python
# -*- coding: utf-8 -*-

from xml.dom.minidom import parseString
import tagconfig
import utils

#The "outExtraInfo" is an out-parameter.
#Its format definition: {'containsMathml': True, 'firstImageSrc': '<img>.src'}
def filter(htmlContent, htmlEncodingMode=False, stripTagMode=False, outExtraInfo=None, mathAmpDecodingMode=False):
    htmlContent = htmlContent.encode('utf-8')
    htmlContent = addRootNode(htmlContent)
    try:
        dom1 = parseString(htmlContent)
    except Exception:
        return None
    except BaseException:
        return None
    rootNode = dom1.childNodes[0]
    return renderDomTree(rootNode, htmlEncodingMode, stripTagMode, outExtraInfo, mathAmpDecodingMode)

def encode(htmlContent):
    return htmlContent
    
def addRootNode(htmlContent):
    #return '<?xml version=\"1.0\" encoding=\"UTF-8\"?><root>' + htmlContent + '</root>'
    return '<root>' + htmlContent + '</root>'

def renderDomTree(node, htmlEncodingMode=False, stripTagMode=False, outExtraInfo=None, mathAmpDecodingMode=False):
    domString = ''
    if node.nodeType == node.ELEMENT_NODE:
        nodeName = node.nodeName
        if type(outExtraInfo) == type({}) and nodeName == 'img':
            if 'firstImageSrc' not in outExtraInfo:
                outExtraInfo['firstImageSrc'] = getImgNodeSrc(node)
        tagInstance = None
        if nodeName in tagconfig.ValidTagConfig['htmlTags']:
            tagInstance = tagconfig.ValidTagConfig['htmlTags'][nodeName]['tagClass'](node, tagconfig.ValidTagConfig, htmlEncodingMode, stripTagMode)
        else:
            if nodeName in tagconfig.ValidTagConfig['mathmlTags']:
                tagInstance = tagconfig.ValidTagConfig['mathmlTags'][nodeName]['tagClass'](node, tagconfig.ValidTagConfig, htmlEncodingMode, stripTagMode)
                if type(outExtraInfo) == type({}):
                    outExtraInfo['containsMathml'] = True
        if tagInstance:
            subNodesData = ''
            startTag = tagInstance.renderStartTag()
            endTag = tagInstance.renderEndTag()
            for subNode in node.childNodes:
                subNodesData += renderDomTree(subNode, htmlEncodingMode, stripTagMode, outExtraInfo, mathAmpDecodingMode)
            domString = startTag + subNodesData + endTag
    else:
        if node.nodeType == node.TEXT_NODE:
            domString = utils.htmlEncode(node.data)
            #The first htmlEncode is for xml.dom.minidom.parseString auto-decoding feature!!
            if htmlEncodingMode:
                domString = utils.htmlEncode(domString)
            if mathAmpDecodingMode:
                parent = node.parentNode
                if parent and parent.nodeName in tagconfig.ValidTagConfig['mathmlTags']:
                    domString = domString.replace('&amp;', '&')
    return domString

def getImgNodeSrc(imgNode):
    attrs = imgNode.attributes
    if attrs:
        for attr in attrs.items():
            attrName = attr[0]
            attrValue = attr[1]
            if attrName == 'src':
                validatorClass = tagconfig.ValidTagConfig['htmlTags']['img']['attributes'][attrName]['validatorClass']
                aValidator = validatorClass(attrValue)
                return  aValidator.filter()
    return ''